#include "common/common.h"
#include "Core/TCFixedString.h"
#include "string/stringoutput.h"
#include "string/stringmanipulations.h"
#include "testlibpilo.h"

using namespace PILO::Core::String;

static INT32 g_id = 0;

INT32 caseOperator_assignA(void * param);
INT32 caseOperator_assignW(void * param);
INT32 caseAssignA(void * param);
INT32 caseAssignW(void * param);
INT32 caseHasValueAtA(void * param);
INT32 caseHasValueAtW(void * param);
INT32 caseOperator_indexA(void * param);
INT32 caseOperator_indexW(void * param);
INT32 caseAtA(void * param);
INT32 caseAtW(void * param);
INT32 caseFormatA(void * param);
INT32 caseFormatW(void * param);
INT32 caseCompareA(void * param);
INT32 caseCompareW(void * param);
INT32 caseIgnoredCompareA(void * param);
INT32 caseIgnoredCompareW(void * param);
INT32 caseOperator_LessThanA(void * param);
INT32 caseOperator_LessThanW(void * param);
INT32 caseOperator_EqualA(void * param);
INT32 caseOperator_EqualW(void * param);
INT32 caseOperator_GreaterThanA(void * param);
INT32 caseOperator_GreaterThanW(void * param);
INT32 caseOperator_NotEqualA(void * param);
INT32 caseOperator_NotEqualW(void * param);
INT32 caseOperator_LessEqualThanA(void * param);
INT32 caseOperator_LessEqualThanW(void * param);
INT32 caseOperator_GreaterEqualThanA(void * param);
INT32 caseOperator_GreaterEqualThanW(void * param);
INT32 caseOperator_leftTrimA(void * param);
INT32 caseOperator_leftTrimW(void * param);
INT32 caseOperator_rightTrimA(void * param);
INT32 caseOperator_rightTrimW(void * param);
INT32 caseOperator_trimA(void * param);
INT32 caseOperator_trimW(void * param);



static case_testing_t g_cases_TCFixedString[] = {
	{1, "TCFixedString<char,10>::operator=                ",                    0,caseOperator_assignA,             -1},
	{2, "TCFixedString<wchar_t,10>::operator=             ",                 0,caseOperator_assignW,             -1},
	{3, "TCFixedString<char,10>::assign                   ",                   0,caseAssignA,                      -1},
	{4, "TCFixedString<wchar_t,10>::assign                ",                0,caseAssignA,                      -1},
	{5, "TCFixedString<char,10>::hasValueAt               ",                   0,caseHasValueAtA,                  -1},
	{6, "TCFixedString<wchar_t,10>::hasValueAt            ",                0,caseHasValueAtW,                  -1},
	{7, "TCFixedString<char,10>::operator[]               ",                   0,caseOperator_indexA,              -1},
	{8, "TCFixedString<wchar_t,10>::operator[]            ",                0,caseOperator_indexW,              -1},
	{9, "TCFixedString<char,10>::at                       ",                 0,caseOperator_indexA,              -1},
	{10,"TCFixedString<wchar_t,10>::at                    ",                 0,caseOperator_indexW,              -1},
	{11,"TCFixedString<char,10>::format                   ",                 0,caseOperator_indexA,              -1},
	{12,"TCFixedString<wchar_t,10>::format                ",                0,caseOperator_indexW,              -1},
	{13,"TCFixedString<char,10>::caseCompare              " ,                 0,caseCompareA,                     -1},
	{14,"TCFixedString<wchar_t,10>::caseCompare           ",               0,caseCompareW,                     -1},
	{15,"TCFixedString<char,10>::caseIgnoredCompare       ",           0,caseIgnoredCompareA,              -1},
	{16,"TCFixedString<wchar_t,10>::caseIgnoredCompare    ",        0,caseIgnoredCompareA,              -1},
	{17,"TCFixedString<char,10>::operator<                ",                0,caseOperator_LessThanA,           -1},
	{18,"TCFixedString<wchar_t,10>::operator<             ",             0,caseOperator_LessThanW,           -1},
	{17,"TCFixedString<char,10>::operator==               ",               0,caseOperator_EqualA,              -1},
	{18,"TCFixedString<wchar_t,10>::operator==            ",                0,caseOperator_EqualW,              -1},
	{19,"TCFixedString<char,10>::operator>                ",                0,caseOperator_GreaterThanA,        -1},
	{20,"TCFixedString<wchar_t,10>::operator>             ",             0,caseOperator_GreaterThanW,        -1},
	{21,"TCFixedString<char,10>::operator!=               ",               0,caseOperator_NotEqualA,           -1},
	{22,"TCFixedString<wchar_t,10>::operator!=            ",                0,caseOperator_NotEqualW,           -1},
	{23,"TCFixedString<char,10>::operator<=               ",               0,caseOperator_LessEqualThanA,      -1},
	{24,"TCFixedString<wchar_t,10>::operator<=            ",                0,caseOperator_LessEqualThanW,      -1},
	{25,"TCFixedString<char,10>::operator>=               ",               0,caseOperator_GreaterEqualThanA,   -1},
	{26,"TCFixedString<wchar_t,10>::operator>=            ",                0,caseOperator_GreaterEqualThanW,   -1},
	{27,"TCFixedString<char,100>::leftTrim                ",                0,caseOperator_leftTrimA,           -1},
	{28,"TCFixedString<wchar_t,100>::leftTrim             ",                 0,caseOperator_leftTrimW,           -1},
	{27,"TCFixedString<char,100>::leftTrim                ",                0,caseOperator_rightTrimA,          -1},
	{28,"TCFixedString<wchar_t,100>::leftTrim             ",                 0,caseOperator_rightTrimW,          -1},
	{29,"TCFixedString<char,100>::trim                    ",                    0,caseOperator_trimA,               -1},
	{30,"TCFixedString<wchar_t,100>::trim                 ",                     0,caseOperator_trimW,               -1},
};


INT32 test_TCFixedString_Functional(INT32 id, int breakOnErrorOccured)
{
	g_id = id;

	FormatOutputToConsole("Testing Part_%d <tcfixedstring.h>\n", id);

	int i=0;
	for (i=0; i<MCF_COUNT_OF(g_cases_TCFixedString); i++) {
		case_testing_t * caseParam = &g_cases_TCFixedString[i];
		ASSERT(caseParam != NULL);
		FormatOutputToConsole(" #[%03d.%03d]: Testing %s ",g_id, caseParam->ct_id, caseParam->ct_decription);

		caseParam->ct_result = caseParam->ct_function(static_cast<case_testing_t *>(caseParam));
		if (caseParam->ct_result == 0) { //ok
			FormatOutputToConsole("[PASSED]\n");
		} else {
			FormatOutputToConsole("[FAILED:%d]\n",caseParam->ct_result);
			if (breakOnErrorOccured) {
				ASSERT(FALSE);
			}
		}
	}

	
	FormatOutputToConsole("Result of Part_%d <tcfixedstring.h/cpp> total  %d, failed %d\n\n",id, MCF_COUNT_OF(g_cases_TCFixedString), failedOFCases(g_cases_TCFixedString,MCF_COUNT_OF(g_cases_TCFixedString)));
	return 0;
}

INT32 caseOperator_assignA(void * )
{

	TCFixedString<char,10> strA("0123456789",10);
	if (strA.compare("012345678")) {
		return -1;
	}
	TCFixedString<char,10> strA2;
	strA2 = strA;
	if ((strA2.size() != 9) || (strA2.compare(strA))) {
		return -2;
    } 
	return 0;
}

INT32 caseOperator_assignW(void * )
{
	TCFixedString<wchar_t,10> str(L"0123456789",10);
	if (str.compare(L"012345678")) {
		return -2;
	}
	TCFixedString<wchar_t,10> str2;
	str2 = str;
	if ((str2.size() != 9) || (str2.compare(str))) {
		return -1;
	} 
	return 0;
}

INT32 caseAssignA(void * )
{
	TCFixedString<char,10> str("0123456789",10);
	str.assign("0123456789abcdefg",10);
	if ((str.size() != 9) || (StringCompare(str.constData(), "012345678"))) {
		return -1;
	}

	return 0;
}
INT32 caseAssignW(void * )
{
	TCFixedString<wchar_t,10> str(L"0123456789",10);
	str.assign(L"0123456789abcdefg",10);
	if ((str.size() != 9) || (StringCompare(str.constData(), L"012345678"))) {
		return -1;
	}

	return 0;
}

INT32 caseHasValueAtA(void * )
{
	TCFixedString<char,10> str("0123456789",10);

	for (int i=0; i<9; i++) {
		if (str.hasValueAt(i) != EnumTriStateYes) {
			return -1;
		}
	}
	if (str.hasValueAt(9) != EnumTriStateNo) {
		return -2;
	}
	if (str.hasValueAt(10) != EnumTriStateNA) {
		return -3;
	}

	return 0;
}

INT32 caseHasValueAtW(void * )
{
	TCFixedString<wchar_t,10> str(L"0123456789",10);

	for (int i=0; i<9; i++) {
		if (str.hasValueAt(i) != EnumTriStateYes) {
			return -1;
		}
	}
	if (str.hasValueAt(9) != EnumTriStateNo) {
		return -2;
	}
	if (str.hasValueAt(10) != EnumTriStateNA) {
		return -3;
	}

	return 0;
}

INT32 caseOperator_indexA(void * )
{
	TCFixedString<char,10> str("0123456789",10);

	for (int i=0; i<9; i++) {
		if (str[i] - 0x30 != i) {
			return -1;
		}
	}
	if(str[9] != 0) {
		return -2;
	}

	return 0;
}
INT32 caseOperator_indexW(void * )
{
	TCFixedString<wchar_t,10> str(L"0123456789",10);

	for (int i=0; i<9; i++) {
		if (str[i] - 0x30 != i) {
			return -1;
		}
	}
	if(str[9] != 0) {
		return -2;
	}

	return 0;
}

INT32 caseAtA(void * )
{
	TCFixedString<char,10> str("0123456789",10);

	for (int i=0; i<9; i++) {
		if (str.at(i) - 0x30 != i) {
			return -1;
		}
	}
	if (str.at(9) != 0) {
		return -1;
	}

	return 0;
}

INT32 caseAtW(void * )
{
	TCFixedString<wchar_t,10> str(L"0123456789",10);

	for (int i=0; i<9; i++) {
		if (str.at(i) - 0x30 != i) {
			return -1;
		}
	}
	if (str.at(9) != 0) {
		return -1;
	}

	return 0;

}

INT32 caseFormatA(void * )
{
	TCFixedString<char,10> str("0123456789",10);

	str.format("%d - %s",13, "fox");
	if (StringCompare(str.constData(), "13 - fox") || (str.size() != 8)) {
		return -1;
	}
	str.format("%d - %s",13, "foxes");
	if (StringCompare(str.constData(), "13 - foxe") || (str.size() != 9)) {
		return -1;
	}
	return 0;
}

INT32 caseFormatW(void * )
{
	TCFixedString<wchar_t,10> str(L"0123456789",10);

	str.format(L"%d - %s",13, "fox");
	if (StringCompare(str.constData(), L"13 - fox") || (str.size() != 8)) {
		return -1;
	}
	str.format(L"%d - %s",13, "foxes");
	if (StringCompare(str.constData(), L"13 - foxe") || (str.size() != 9)) {
		return -1;
	}
	return 0;
}

INT32 caseCompareA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345678";
	str2 = "012345678";

	if (str1.compare(str2.constData())) {
		return -1;
	}
	str2 = "123456789";
	if (str1.compare(str2.constData())>=0) {
		return -2;
	}
	str2 = str2.makeInvalid();
	str1 = str1.makeEmpty();

	if (str1.compare(NULL) != 0) {
		return -3;
	}

	str2 = "012345xxx";
	str1 = "012345678";
	if (str1.compare(str2.constData(),6)) {
		return -4;
	}

	return 0;
}

INT32 caseCompareW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345678";
	str2 = L"012345678";

	if (str1.compare(str2.constData())) {
		return -1;
	}
	str2 = L"123456789";
	if (str1.compare(str2.constData())>=0) {
		return -2;
	}
	str2 = str2.makeInvalid();
	str1 = str1.makeEmpty();

	if (str1.compare(NULL) != 0) {
		return -3;
	}

	str2 = L"012345xxx";
	str1 = L"012345678";
	if (str1.compare(str2.constData(),6)) {
		return -4;
	}

	return 0;
}

INT32 caseIgnoredCompareA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "ad MAPIf";
	str2  = "AD MAPIF";
	if (str1.caseIgnoredCompare(str2.constData())) {
		return -1;
	}
	str1 = "ad MAPIfx";
	str2  = "AD MAPIFy";
	if (str1.caseIgnoredCompare(str2.constData(),8)) {
		return -2;
	}

	return 0;

}
INT32 caseIgnoredCompareW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"ad MAPIf";
	str2  = L"AD MAPIF";
	if (str1.caseIgnoredCompare(str2.constData())) {
		return -1;
	}
	str1 = L"ad MAPIfx";
	str2  = L"AD MAPIFy";
	if (str1.caseIgnoredCompare(str2.constData(),8)) {
		return -2;
	}

	return 0;
}


INT32 caseOperator_EqualA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345xxx";
	str2  = "012345xxx";
	if (str2 == str1) {
		return 0;
	}

	return -1;
}

INT32 caseOperator_EqualW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345xxx";
	str2  = L"012345xxx";
	if (str2 == str1) {
		return 0;
	}

	return -1;
}

INT32 caseOperator_GreaterThanA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345xxx";
	str2  = "012345678";
	if (str2 > str1) {
		return -1;
	}

	return -0;
}

INT32 caseOperator_GreaterThanW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345xxx";
	str2  = L"012345678";
	if (str2 > str1) {
		return -1;
	}

	return -0;
}

INT32 caseOperator_LessThanA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345xxx";
	str2  = "012345678";
	if (str2 < str1) {
		return 0;
	}

	return -1;
}
INT32 caseOperator_LessThanW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345xxx";
	str2  = L"012345678";
	if (str2 < str1) {
		return 0;
	}

	return -1;
}

INT32 caseOperator_NotEqualA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345xxx";
	str2  = "012345678";
	if (str2 != str1) {
		return 0;
	}

	return -1;
}

INT32 caseOperator_NotEqualW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345xxx";
	str2  = L"012345678";
	if (str2 != str1) {
		return 0;
	}

	return -1;
}

INT32 caseOperator_LessEqualThanA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345xxx";
	str2  = "012345678";
	if (str2 <= str1) {
		return 0;
	}

	return -1;
}


INT32 caseOperator_LessEqualThanW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345xxx";
	str2  = L"012345678";
	if (str2 <= str1) {
		return 0;
	}

	return -1;
}

INT32 caseOperator_GreaterEqualThanA(void * )
{
	TCFixedString<char,10> str1;
	TCFixedString<char,10> str2;

	str1 = "012345xxx";
	str2  = "012345678";
	if (str2 >= str1) {
		return -1;
	}

	return -0;
}

INT32 caseOperator_GreaterEqualThanW(void * )
{
	TCFixedString<wchar_t,10> str1;
	TCFixedString<wchar_t,10> str2;

	str1 = L"012345xxx";
	str2  = L"012345678";
	if (str2 >= str1) {
		return -1;
	}

	return -0;
}

INT32 caseOperator_leftTrimA(void * )
{
	TCFixedString<char,100> strA("0123456789",10);

	if (strA.leftTrim().compare("0123456789") != 0) {
		return -1;
	}

	strA = "	     abcd    ";
	if (strA.leftTrim().compare("abcd    ") != 0) {
		return -2;
	}

	return 0;
}
INT32 caseOperator_leftTrimW(void * )
{
	TCFixedString<wchar_t,100> strW(L"0123456789",10);

	if (strW.leftTrim().compare(L"0123456789") != 0) {
		return -1;
	}

	strW = L"	     abcd    ";
	if (strW.leftTrim().compare(L"abcd    ") != 0) {
		return -2;
	}

	return 0;

}

INT32 caseOperator_rightTrimA(void * )
{
	TCFixedString<char,100> strA("0123456789",10);

	if (strA.rightTrim().compare("0123456789") != 0) {
		return -1;
	}

	strA = "	     abcd    ";
	if (strA.rightTrim().compare("	     abcd") != 0) {
		return -2;
	}

	return 0;
}

INT32 caseOperator_rightTrimW(void * )
{
	TCFixedString<wchar_t,100> strW(L"0123456789",10);

	if (strW.rightTrim().compare(L"0123456789") != 0) {
		return -1;
	}

	strW = L"	     abcd    ";
	if (strW.rightTrim().compare(L"	     abcd") != 0) {
		return -2;
	}

	return 0;
}

INT32 caseOperator_trimA(void * )
{
	TCFixedString<char,100> strA("0123456789",10);

	if (strA.trim().compare("0123456789") != 0) {
		return -1;
	}

	strA = "	     abcd    ";
	if (strA.trim().compare("abcd") != 0) {
		return -2;
	}

	return 0;

}

INT32 caseOperator_trimW(void * )
{
	TCFixedString<wchar_t,100> strW(L"0123456789",10);

	if (strW.trim().compare(L"0123456789") != 0) {
		return -1;
	}

	strW = L"	     abcd    ";
	if (strW.trim().compare(L"abcd") != 0) {
		return -2;
	}

	return 0;
}

